package com.jdd.modules.parking.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jdd.common.api.vo.Result;
import com.jdd.common.aspect.annotation.*;
import com.jdd.common.constant.CommonConstant;
import com.jdd.common.constant.JddConstant;
import com.jdd.common.system.query.QueryGenerator;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.DateUtil;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.SnowFlakeUtil;
import com.jdd.common.util.oConvertUtils;
import com.jdd.modules.configcartype.entity.ConfigCarType;
import com.jdd.modules.configcartype.service.IConfigCarTypeService;
import com.jdd.modules.operationLog.entity.ParkHandOverLog;
import com.jdd.modules.operationLog.mapper.ParkHandOverLogMapper;
import com.jdd.modules.operationLog.service.IParkHandOverLogService;
import com.jdd.modules.order.entity.ParkOrderInfo;
import com.jdd.modules.order.service.IParkOrderInfoService;
import com.jdd.modules.parking.entity.*;
import com.jdd.modules.parking.service.*;
import com.jdd.modules.parking.util.IpAddressCheckUtil;
import com.jdd.modules.sdk.SdkCallInterface;
import com.jdd.modules.sdkidentifyresultpushlog.entity.SaveArmMacVo;
import com.jdd.modules.system.model.TreeModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * @Description: 车场出入口配置
 * @Author: jdd
 * @Date: 2021-02-15
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "车场出入口配置")
@RestController
@RequestMapping("/parking/parkArmInfo")
@Valid
public class ParkArmInfoController {
    @Autowired
    private IParkArmInfoService parkArmInfoService;
    @Autowired
    private IConfigParkThroughService configParkThroughService;

    @Autowired
    private IConfigParkInfoService configParkInfoService;

    @Autowired
    private IparkCarEnterLogService parkCarEnterLogService;

    @Autowired
    private IParkOrderInfoService parkOrderInfoService;

    @Autowired
    private IparkCarOutLogService parkCarOutLogService;

    @Autowired
    private IParkInfoService parkInfoService;

    @Autowired
    ExecutorService executorService;

    @Autowired
    private IConfigCarTypeService configCarTypeService;

    @Autowired
    private SdkCallInterface sdkCallInterface;
    @Autowired
    private IParkWorkStationService parkWorkStationService;
    @Autowired
    private IParkHandOverLogService parkHandOverLogService;
    @Resource
    private ParkHandOverLogMapper parkHandOverLogMapper;

    /**
     * 监控中心获取数据
     *
     * @param req
     * @return
     */
    @AutoLog(value = "监控中心获取数据")
    @ApiOperation(value = "监控中心获取数据", notes = "监控中心获取数据查询")
    @GetMapping(value = "/getData")
    public Result getData(String userId, String workstationId, HttpServletRequest req) {
        Result result = new Result<>();
        // 返回数据data
        Map data = new HashMap();
        //属于当前登录人且状态为开启的车道
        List<ParkArmInfo> pageList = parkArmInfoService.lambdaQuery().eq(ParkArmInfo::getWorkStationId, workstationId).eq(ParkArmInfo::getArmStatus,JddConstant.StringNumber.STRING_ONE).list();
        //拿到登录人信息
        String workUserName = null;
        if(ObjectUtil.isNotEmpty(pageList)) {
            workUserName = parkWorkStationService.getStationOperationNameByParkArm(pageList.get(0));
        }

        //所有车道的信息，前端需要的
        CompletableFuture allParkArm = CompletableFuture.runAsync(() -> {
            //所有的车道信息
            List<ParkArmInfo> list = parkArmInfoService.list();
            data.put("allParkArm", list);
        }, executorService);

        // 车道信息
        CompletableFuture parkArmFuture = CompletableFuture.runAsync(() -> {
            ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
            // 车道信息
            // 当前监控能来回选择的车道
            data.put("CameraType",configParkInfo!=null?configParkInfo.getCameraType():null);
            data.put("parkArm", pageList);
        }, executorService);

        // 车辆类型
        CompletableFuture configCarTypeFuture = CompletableFuture.runAsync(() -> {
            // 车道信息
            //这里为什么要只查2条？如果有好几条配置，出去得车辆不属于当前这个配置会不现实
            List<ConfigCarType> listCarType = configCarTypeService.lambdaQuery().eq(ConfigCarType::getCarType, "0").or().eq(ConfigCarType::getCarType, "2")
                    .last("limit 6").list();
            data.put("carType", listCarType);
        }, executorService);


        // 车位信息
        CompletableFuture totalParkSpaceFuture = CompletableFuture.runAsync(() -> {

            // 总的停车位信息
            int totalParkSpace = configParkInfoService.lambdaQuery().list().size() > 0 ?
                    configParkInfoService.lambdaQuery().list().get(0).getTemporaryParking() : 0;

            // 未出场、场内临时车辆数量
            //临时车
//            int parkSpace = parkCarEnterLogService.lambdaQuery().eq(ParkCarEnterLog::getIsOut, "0").eq(ParkCarEnterLog::getCarNature, "0").count();
            QueryWrapper<ParkCarEnterLog> parkSpaceQueryWrapper = new QueryWrapper<>();
            parkSpaceQueryWrapper.select("DISTINCT(plate_no)");
            parkSpaceQueryWrapper.eq("is_out", "0");
            parkSpaceQueryWrapper.eq("car_nature", "0");
            int parkSpace = parkCarEnterLogService.count(parkSpaceQueryWrapper);

            //固定车，储值车,JddConstant.MqttRecResultPushLog.IS_WHITE_ONE是月租车
//            int parkSpaceLong = parkCarEnterLogService.lambdaQuery().eq(ParkCarEnterLog::getIsOut, "0").in(ParkCarEnterLog::getCarNature, JddConstant.StringNumber.STRING_ONE, JddConstant.StringNumber.STRING_TWO).count();
            QueryWrapper<ParkCarEnterLog> parkSpaceLongQueryWrapper = new QueryWrapper<>();
            parkSpaceLongQueryWrapper.select("DISTINCT(plate_no)");
            parkSpaceLongQueryWrapper.eq("is_out", "0");
            parkSpaceLongQueryWrapper.in("car_nature", Arrays.asList(JddConstant.StringNumber.STRING_ONE, JddConstant.StringNumber.STRING_TWO));
            int parkSpaceLong = parkCarEnterLogService.count(parkSpaceLongQueryWrapper);

            //其他车（警车，白名单）
//            int parkSpaceOther = parkCarEnterLogService.lambdaQuery().eq(ParkCarEnterLog::getIsOut, "0").in(ParkCarEnterLog::getCarNature, JddConstant.StringNumber.STRING_THREE, JddConstant.StringNumber.STRING_FOUR).count();
            QueryWrapper<ParkCarEnterLog> parkSpaceOtherQueryWrapper = new QueryWrapper<>();
            parkSpaceOtherQueryWrapper.select("DISTINCT(plate_no)");
            parkSpaceOtherQueryWrapper.eq("is_out", "0");
            parkSpaceOtherQueryWrapper.in("car_nature", Arrays.asList(JddConstant.StringNumber.STRING_THREE, JddConstant.StringNumber.STRING_FOUR));
            int parkSpaceOther = parkCarEnterLogService.count(parkSpaceOtherQueryWrapper);

            // 剩余车位数量
            int remainingPark = (totalParkSpace - parkSpace) < 0 ? 0 : (totalParkSpace - parkSpace);
            // 总停车位信息
            data.put("totalParkSpace", totalParkSpace);
            // 场内临时车数量
            data.put("parkSpace", parkSpace);
            // 场内固定车数量
            data.put("parkSpaceLong", parkSpaceLong);
            // 场内其他车数量
            data.put("parkSpaceOther", parkSpaceOther);
            // 剩余车位数量
            data.put("remainingPark", remainingPark);

        }, executorService);

        // 订单数量
        CompletableFuture countOrderFuture = CompletableFuture.runAsync(() -> {

            // 今日订单数量
            int countOrder =
                    parkOrderInfoService.lambdaQuery().eq(ParkOrderInfo::getOrderStatus, "2").ge(ParkOrderInfo::getCreateTime, DateUtil.getDay() + " 00:00:00").count();

            data.put("countOrder", countOrder);

        }, executorService);

        // 如果是岗亭人员登录
        // 工作站/交接班信息
        String finalWorkUserName = workUserName;
        CompletableFuture workStationFuture = CompletableFuture.runAsync(() -> {
            if(ObjectUtil.isNotEmpty(finalWorkUserName)) {
                QueryWrapper<ParkHandOverLog> wrapper = new QueryWrapper<>();
                wrapper.eq("operation_name", finalWorkUserName);
                wrapper.orderByDesc("create_time");
                wrapper.isNull("hand_over_name");
                wrapper.last(" limit 1");
                ParkHandOverLog parkHandOverLog = parkHandOverLogMapper.selectOne(wrapper);
                if (parkHandOverLog != null) {
                    data.put("HandOverLog", parkHandOverLog);
                }
            }

        }, executorService);

        String finalWorkUserName1 = workUserName;
        CompletableFuture todayOrderSumFuture = CompletableFuture.runAsync(() -> {

            if(finalWorkUserName1!=null) {
                QueryWrapper<ParkHandOverLog> wrapper = new QueryWrapper<>();
                wrapper.eq("operation_name", finalWorkUserName1);
                wrapper.orderByDesc("create_time");
                wrapper.isNull("hand_over_name");
                wrapper.last(" limit 1");
                ParkHandOverLog parkHandOverLog = parkHandOverLogService.getOne(wrapper);
                if(parkHandOverLog!=null) {
                    data.put("todayOrderSum", parkHandOverLog.getManualPaid());
                }
            }
        }, executorService);


        CompletableFuture orderFuture = CompletableFuture.runAsync(() -> {
            ParkInfo parkInfo = null;
            // 订单信息
            List<ParkOrderInfo> parkOrderInfos =
                    parkOrderInfoService.lambdaQuery().eq(ParkOrderInfo::getOrderStatus, "2").orderByDesc(ParkOrderInfo::getCreateTime).last(" limit " +
                            "20").list();

            // 入场信息
            List<ParkCarEnterLog> parkCarEnterLogs = parkCarEnterLogService.lambdaQuery().orderByDesc(ParkCarEnterLog::getCreateTime).last(" " +
                    "limit 20").list();

            List<ParkInfo> list = parkInfoService.list();
            if (list != null || !list.isEmpty()) {
                parkInfo = list.get(0);
            }

            // 出场信息
            List<ParkCarOutLog> parkCarOutLogs =
                    parkCarOutLogService.lambdaQuery().orderByDesc(ParkCarOutLog::getCreateTime).last(" limit 20").list();

            // 场内信息
            List<ParkCarEnterLog> inParkinglotCar =
                    parkCarEnterLogService.lambdaQuery().eq(ParkCarEnterLog::getIsOut, JddConstant.StringNumber.STRING_ZERO)
                            .ne(ParkCarEnterLog::getIsTransfer, JddConstant.StringNumber.STRING_ONE).orderByDesc(ParkCarEnterLog::getCreateTime).last(" limit 20").list();


            data.put("parkName", parkInfo.getParkName());
            data.put("parkOrderInfos", parkOrderInfos);
            data.put("parkCarEnterLogs", parkCarEnterLogs);
            data.put("parkCarOutLogs", parkCarOutLogs);
            data.put("inParkinglotCar", inParkinglotCar);

        }, executorService);

        try {
            CompletableFuture.allOf(allParkArm,parkArmFuture,workStationFuture, configCarTypeFuture, totalParkSpaceFuture, countOrderFuture, todayOrderSumFuture, orderFuture).get();
        } catch (Exception e) {
            log.error("监控页面，线程执行异常或创建交接班记录失败：{}", e.getMessage());
        }
        result.setSuccess(true);
        result.setResult(data);
        return result;
    }


    @AutoLog(value = "查询当前工作站下所管辖得车道")
    @ApiOperation(value = "查询当前工作站下所管辖得车道", notes = "查询当前工作站下所管辖得车道")
    @GetMapping(value = "/monitorFromStation")
    public Result<List<ParkArmInfo>> monitorFromStation(@RequestParam String workStationId) {
        Result<List<ParkArmInfo>> result = new Result<>();
        try {
            List<ParkArmInfo> armInfos = parkArmInfoService.workStationId(workStationId);
            result.setSuccess(true);
            result.setResult(armInfos);
        }catch (Exception e){
            result.setSuccess(false);
            result.setResult(null);
        }
        return result;
    }

    @AutoLog(value = "监控查询车道名称")
    @ApiOperation(value = "监控查询车道名称", notes = "监控查询车道名称")
    @GetMapping(value = "/monitorArmList")
    public Result<List<ParkArmInfo>> queryPageList(@RequestParam String workName,
                                                    @RequestParam String type) {
        Result<List<ParkArmInfo>> result = new Result<>();
        try {
            List<ParkArmInfo> parkArmInfos = parkArmInfoService.monitorArmList(workName, type);
            result.setSuccess(true);
            result.setResult(parkArmInfos);
        }catch (Exception e){
            result.setSuccess(false);
            result.setResult(null);
        }
        return result;
    }
    /**
     * 分页列表查询
     *
     * @param parkArmInfo
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "车场出入口配置-分页列表查询")
    @ApiOperation(value = "车场出入口配置-分页列表查询", notes = "车场出入口配置-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<ParkArmInfo>> queryPageList(ParkArmInfo parkArmInfo,
                                                    @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                    @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, String startTime, String endTime,
                                                    HttpServletRequest req) {
        Result<IPage<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = QueryGenerator.initQueryWrapper(parkArmInfo, req.getParameterMap());
        if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
            queryWrapper.and(wrapper -> wrapper.ge("create_time", startTime + " 00:00:00").le("create_time", endTime + " 23:59:59"));
        }
        Page<ParkArmInfo> page = new Page<>(pageNo, pageSize);
        IPage<ParkArmInfo> pageList = parkArmInfoService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    @AutoLog(value = "指定车场入口车道列表查询")
    @ApiOperation(value = "指定车场入口车道列表查询", notes = "指定车场入口车道列表查询")
    @RequestMapping(value = "/getArmList")
    public Result<Map<String, Object>> getArmList(HttpServletRequest req) {
        Result<Map<String, Object>> result = new Result<>();
        List<ParkArmInfo> pageList = parkArmInfoService.findParkArmInfosByParkCode();
        Map<String, Object> resMap = new HashMap<String, Object>();
        List<TreeModel> treeList = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        for (ParkArmInfo arm : pageList) {
            TreeModel tree = new TreeModel(arm.getId(), "", arm.getArmName(), 0, false);
            ids.add(arm.getId());
            treeList.add(tree);
        }
        resMap.put("treeList", treeList);
        resMap.put("ids", ids);
        result.setResult(resMap);
        result.setSuccess(true);
        return result;
    }

    /**
     * 车道配置信息
     *
     * @param parkArmInfo
     * @param req
     * @return
     */
    @AutoLog(value = "车场入口车道列表查询")
    @ApiOperation(value = "指定车场入口车道列表查询", notes = "指定车场入口车道列表查询")
    @RequestMapping(value = "/getArmListByMac")
    public Result<List<String>> getArmListByMac(ParkArmInfo parkArmInfo,
                                                HttpServletRequest req) {
        Result<List<String>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = QueryGenerator.initQueryWrapper(parkArmInfo, req.getParameterMap());
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setResult(pageList.stream().map(ParkArmInfo -> String.valueOf(ParkArmInfo.getId())).collect(Collectors.toList()));
        result.setSuccess(true);
        return result;
    }
    /**
     * 车道配置信息
     *
     * @param parkArmInfo
     * @param req
     * @return
     */
    @AutoLog(value = "车场入口车道列表查询")
    @ApiOperation(value = "指定车场入口车道列表查询", notes = "指定车场入口车道列表查询")
    @RequestMapping(value = "/selectOutArmList")
    public Result<List<ParkArmInfo>> selectOutArmList(ParkArmInfo parkArmInfo,
                                                HttpServletRequest req) {
        Result<List<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = QueryGenerator.initQueryWrapper(parkArmInfo, req.getParameterMap());
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setResult(pageList);
        result.setSuccess(true);
        return result;
    }   /**
     * 车道配置信息
     *
     * @param parkArmInfo
     * @param req
     * @return
     */
    @AutoLog(value = "车场入口车道列表查询")
    @ApiOperation(value = "指定车场入口车道列表查询", notes = "指定车场入口车道列表查询")
    @RequestMapping(value = "/selectEntArmList")
    public Result<List<ParkArmInfo>> selectEntArmList(ParkArmInfo parkArmInfo,
                                                   HttpServletRequest req) {
        Result<List<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = QueryGenerator.initQueryWrapper(parkArmInfo, req.getParameterMap());
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setResult(pageList);
        result.setSuccess(true);
        return result;
    }
    @AutoLog(value = "车场出入口配置-通过车场编号")
    @ApiOperation(value = "车场出入口配置-通过车场编号", notes = "车场出入口配置-通过车场编号")
    @GetMapping(value = "/parkArmInfoList")
    public Result<List<ParkArmInfo>> parkArmList() {
        Result<List<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = new QueryWrapper<ParkArmInfo>();
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    @AutoLog(value = "工作站新增-查询启用的车道")
    @ApiOperation(value = "工作站新增-查询启用的车道", notes = "工作站新增-查询启用的车道")
    @GetMapping(value = "/parkArmInfoListStatusOk")
    public Result<List<ParkArmInfo>> parkArmInfoListStatusOk() {
        Result<List<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = new QueryWrapper<ParkArmInfo>();
        queryWrapper.eq("arm_status",JddConstant.StringNumber.STRING_ONE);
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 保存监控车道数据
     *
     * @param json
     * @return
     */
    @AutoLog(value = "车场出入口配置-添加")
    @ApiOperation(value = "车场出入口配置-添加", notes = "车场出入口配置-添加")
    @PostMapping(value = "/saveArm")
    @OperationLogDetail(detail = "车场出入口配置，保存监控车道数据", level = LogLevelType.ONE, operationType = OperationType.INSERT, operationUnit = OperationUnit.UNKNOWN)
    public Result<String> saveArm(@RequestBody JSONObject json) {
        Result<String> result = new Result<>();
        String userId = LoginUserUtils.getLoginUser().getId();
        try {
            String permissionIds = json.getString("permissionIds");
            String lastPermissionIds = json.getString("lastpermissionIds");
            List<String> add = getDiff(lastPermissionIds, permissionIds);
            if (add != null && add.size() > 0) {
                for (String p : add) {
                    ParkArmInfo parkArmInfo = new ParkArmInfo();
                    parkArmInfo.setUsedUserId(userId);
                    parkArmInfo.setId(p);
                    parkArmInfoService.updateById(parkArmInfo);
                }
            }
            List<String> delete = getDiff(permissionIds, lastPermissionIds);
            if (delete != null && delete.size() > 0) {
                for (String id : delete) {
                    ParkArmInfo parkArmInfo = new ParkArmInfo();
                    parkArmInfo.setUsedUserId(userId);
                    parkArmInfo.setId(id);
                    parkArmInfoService.updateById(parkArmInfo);
                }
            }
            result.success("操作成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }

    private List<String> getDiff(String main, String diff) {
        if (oConvertUtils.isEmpty(diff)) {
            return null;
        }
        if (oConvertUtils.isEmpty(main)) {
            return Arrays.asList(diff.split(","));
        }
        String[] mainArr = main.split(",");
        String[] diffArr = diff.split(",");
        Map<String, Integer> map = new HashMap<>();
        for (String string : mainArr) {
            map.put(string, 1);
        }
        List<String> res = new ArrayList<String>();
        for (String key : diffArr) {
            if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) {
                res.add(key);
            }
        }
        return res;
    }

    /**
     * 添加
     *
     * @param parkArmInfo
     * @return
     */
    @AutoLog(value = "车场出入口配置-添加")
    @ApiOperation(value = "车场出入口配置-添加", notes = "车场出入口配置-添加")
    @PostMapping(value = "/add")
    @OperationLogDetail(detail = "车场出入口配置，添加", level = LogLevelType.ONE, operationType = OperationType.INSERT, operationUnit = OperationUnit.UNKNOWN)
    public Result<ParkArmInfo> add(@RequestBody ParkArmInfo parkArmInfo) {
        Result<ParkArmInfo> result = new Result<>();
        try {
            LoginUser loginUser = LoginUserUtils.getLoginUser();
            LambdaQueryWrapper<ParkArmInfo> serialNoQueryWrapper = new LambdaQueryWrapper<>();
            serialNoQueryWrapper.eq(ParkArmInfo::getSerialNo, parkArmInfo.getSerialNo());
            LambdaQueryWrapper<ParkArmInfo> ipQueryWrapper = new LambdaQueryWrapper<>();
            ipQueryWrapper.eq(ParkArmInfo::getIpAddr, parkArmInfo.getIpAddr());

            ConfigParkInfo configParkInfo = getConfigParkInfo();
            if (ObjectUtil.isNull(configParkInfo)) {
                return result.error500("车辆信息配置为空");
            } else if (parkArmInfoService.getOne(serialNoQueryWrapper) != null) {
                //如果存在相同的设备序列号
                result.error500("重复的设备序列号");
            } else if (parkArmInfoService.getOne(ipQueryWrapper) != null) {
                //如果存在相同的Ip地址
                result.error500("ip地址不能够重复");
            } else {
                parkArmInfo.setCreateUser(loginUser.getUsername());
                parkArmInfo.setId(SnowFlakeUtil.getId());
                //根据相机类型获拼接频流rtsp地址
                String rtspUrl = parkArmInfoService.jointRtspUrl(parkArmInfo, configParkInfo);
                if (StringUtils.isNotBlank(rtspUrl)) {
                    parkArmInfo.setRtspUrl(parkArmInfoService.jointRtspUrl(parkArmInfo, configParkInfo));
                }
                //根据相机类型拼接视频流video地址
                parkArmInfo.setVideoUrl(parkArmInfoService.jointVideoUrl(parkArmInfo, configParkInfo));

                parkArmInfoService.saveEntity(parkArmInfo);
                //编辑和添加前判断状态
                Result isConnect = sdkCallInterface.GetIsConnect(parkArmInfo.getSerialNo());
                if (CommonConstant.SC_OK_200.equals(isConnect.getCode())) {
                    return result.success("该设备添加成功,并且添加前已经初始化成功");
                }
                //初始化相机
                result = sdkCallInterface.CameraSdkInit(parkArmInfo.getIpAddr(), configParkInfo);
                if (result.getCode() == 200) {
                    result.success("添加成功！");
                } else {
                    result.error500("设备初始化失败请检查网络连接状态");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }



    /**
     * 编辑
     *
     * @param parkArmInfo
     * @return
     */
    @AutoLog(value = "车场出入口配置-编辑")
    @ApiOperation(value = "车场出入口配置-编辑", notes = "车场出入口配置-编辑")
    @PutMapping(value = "/edit")
    @OperationLogDetail(detail = "车场出入口配置，编辑", level = LogLevelType.ONE, operationType = OperationType.UPDATE, operationUnit = OperationUnit.UNKNOWN)
    public Result<ParkArmInfo> edit(@RequestBody ParkArmInfo parkArmInfo) {
        Result<ParkArmInfo> result = new Result<>();
        ConfigParkInfo configParkInfo = getConfigParkInfo();

        // 根据ID查询数据库中是否存在该数据
        ParkArmInfo parkArmInfoEntity = parkArmInfoService.getById(parkArmInfo.getId());
        if (parkArmInfoEntity == null) {
            // 如果不存在
            result.error500("未找到对应实体");
        } else {
            // 如果存在，检测设备序列号是否为空
            if (!StringUtils.isNotBlank(parkArmInfo.getSerialNo())) {
                return Result.error("设备序列号不能为空");
            }
            // 检测车道名称是否为空
            if (!StringUtils.isNotBlank(parkArmInfo.getArmName())) {
                return Result.error("车道名称不能为空");
            }
            if (!IpAddressCheckUtil.checkPlateNo(parkArmInfo.getIpAddr())) {
                return Result.error("Ip地址格式错误");
            }

            LambdaQueryWrapper<ParkArmInfo> serialNoQueryWrapper = new LambdaQueryWrapper<>();
            serialNoQueryWrapper.eq(ParkArmInfo::getSerialNo, parkArmInfo.getSerialNo());
            LambdaQueryWrapper<ParkArmInfo> ipQueryWrapper = new LambdaQueryWrapper<>();
            ipQueryWrapper.eq(ParkArmInfo::getIpAddr, parkArmInfo.getIpAddr());
            ParkArmInfo sameSerialNoInfo = parkArmInfoService.getOne(serialNoQueryWrapper);
            ParkArmInfo sameIpInfo = parkArmInfoService.getOne(ipQueryWrapper);

            if (sameSerialNoInfo != null && !parkArmInfo.getId().equals(sameSerialNoInfo.getId())) {
                // 如果存在相同的设备序列号,且Id不一致
                result.error500("重复的设备序列号");
            } else if (sameIpInfo != null && !parkArmInfo.getId().equals(sameIpInfo.getId())) {
                // 如果存在相同的Ip地址
                result.error500("ip地址不能够重复");
            } else {
                // 若数据一切正常
                // 如果传入的车道信息的车道类型是出口的话
                if (JddConstant.ParkArmInfo.ARM_TYPE_ONE.equals(parkArmInfo.getArmType())) {
                    // 移除通行配置表中的该车道信息的通行设置
                    configParkThroughService.deleteEntityBySerialNo(parkArmInfo.getSerialNo());
                }
                // 如果车道信息的设备序列号被编辑了
                if (!parkArmInfoEntity.getSerialNo().equals(parkArmInfo.getSerialNo())) {
                    // 得到该车道信息配置的通行配置
                    ConfigParkThrough configParkThrough = configParkThroughService.queryConfigParkThrough(parkArmInfo.getSerialNo());
                    // 如果通行配置存在
                    if (configParkThrough != null) {
                        // 修改该通行配置的设备序列号
                        configParkThrough.setSerialNo(parkArmInfo.getSerialNo());
                        configParkThroughService.updateEntity(configParkThrough);
                    }
                }
                //根据相机类型获拼接频流rtsp地址
                parkArmInfo.setRtspUrl(parkArmInfoService.jointRtspUrl(parkArmInfo, configParkInfo));
                //根据相机类型拼接视频流video地址
                parkArmInfo.setVideoUrl(parkArmInfoService.jointVideoUrl(parkArmInfo, configParkInfo));
                boolean ok = parkArmInfoService.updateEntity(parkArmInfo);
                if (ok) {
                    if (ObjectUtil.isNull(configParkInfo)) {
                        return result.error500("车辆信息配置为空");
                    }
                    //编辑和添加前判断状态
                    Result isConnect = sdkCallInterface.GetIsConnect(parkArmInfo.getSerialNo());
                    if (CommonConstant.SC_OK_200.equals(isConnect.getCode())) {
                        return result.success("该设备添加成功,并且添加前已经初始化成功");
                    }
                    result = sdkCallInterface.CameraSdkInit(parkArmInfo.getIpAddr(), configParkInfo);
                    // 若更新操作正常
                    if (result.getCode() == 200) {
                        result.success("修改成功！");
                    } else {
                        result.error500("修改成功:设备初始化失败请检查网络连接状态");
                    }
                }
            }
        }
        return result;
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车场出入口配置-通过id删除")
    @ApiOperation(value = "车场出入口配置-通过id删除", notes = "车场出入口配置-通过id删除")
    @DeleteMapping(value = "/delete")
    @OperationLogDetail(detail = "车场出入口配置，通过id删除", level = LogLevelType.ONE, operationType = OperationType.DELETE, operationUnit = OperationUnit.UNKNOWN)
    public Result<?> delete(@RequestParam(name = "invateuserdetailId", required = true) String id) {

        try {
            // 根据传入的被删除的车场车道信息的id,得到被删除的车场车道信息
            ParkArmInfo parkArmInfo = parkArmInfoService.getById(id);
            // 如果车场车道信息存在
            if (parkArmInfo != null) {
                configParkThroughService.deleteEntityBySerialNo(parkArmInfo.getSerialNo());
            }
            parkArmInfoService.deleteEntityById(id);
        } catch (Exception e) {
            log.error("删除失败", e.getMessage());
            return Result.error("删除失败!");
        }
        return Result.ok("删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "车场出入口配置-通过id查询")
    @ApiOperation(value = "车场出入口配置-通过id查询", notes = "车场出入口配置-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ParkArmInfo> queryById(@RequestParam(name = "id", required = true) String id) {
        Result<ParkArmInfo> result = new Result<ParkArmInfo>();
        ParkArmInfo parkArmInfo = parkArmInfoService.getById(id);
        ConfigParkInfo configParkInfo = configParkInfoService.findConfigParkInfoByParkCode();
        if (ObjectUtil.isNull(configParkInfo)) {
            return Result.error(510, "车辆信息配置为空，请检查");
        }
        parkArmInfo.setParkCode(configParkInfo.getParkCode());
        if (parkArmInfo == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(parkArmInfo);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 指定车场车辆类型列表查询
     *
     * @param
     * @return
     **/
    @AutoLog(value = "指定车场入口车道列表查询")
    @ApiOperation(value = "指定车场入口车道列表查询", notes = "指定车场入口车道列表查询")
    @RequestMapping(value = "/ParkArmList")
    public Result<List<ParkArmInfo>> parkCarTypeList(ParkArmInfo parkArmInfo,
                                                     HttpServletRequest req) {
        Result<List<ParkArmInfo>> result = new Result<>();
        List<ParkArmInfo> pageList;
        pageList = parkArmInfoService.findParkEnterArmInfos();
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 获取车场设备信息
     **/
    @AutoLog(value = "获取车场设备信息列表查询")
    @ApiOperation(value = "获取车场设备信息列表查询", notes = "获取车场设备信息列表查询")
    @GetMapping(value = "/getParkArmList")
    public Result<List<ParkArmInfo>> getParkArmList() {
        Result<List<ParkArmInfo>> result = new Result<>();
        List<ParkArmInfo> pageList = parkArmInfoService.findParkArmInfosByParkCode();
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }
    /*
     * @author lcy
     * @date 2021/9/2
     * @Description 切换相机后，将used_user_id地址赋值给切换到的相机
     */
    @AutoLog(value = "used_user_id地址赋值给切换到的相机")
    @ApiOperation(value = "used_user_id地址赋值给切换到的相机",notes = "used_user_id地址赋值给切换到的相机")
    @PostMapping(value = "/saveArmMac")
    public Result saveArmMac(@RequestBody SaveArmMacVo saveArmMacVo){
        return Result.ok("无需更换userid");
    }

    private ConfigParkInfo getConfigParkInfo() {
        //拿到配置决定初始化哪个相机
        return configParkInfoService.findConfigParkInfoByParkCode();
    }

    /**
     * 根据车辆编号、车牌类型匹配停车场的车辆类型Id
     *
     * @param type 车牌类型
     * @return java.lang.String
     * @version 1.0
     */
    private String getCarType(int type) {
        String result = null;
        List<ConfigCarType> list = configCarTypeService.getCarTypeList();
        for (ConfigCarType carType : list) {
            String cardTypeId = carType.getId();
            String carTypeName = carType.getCarTypeName();
            List<String> typeNo = Arrays.asList(carType.getCarTypeNo().split(","));
            if (typeNo.contains(type + "")) {
                result = carTypeName;
                return result;
            }
        }
        return result;
    }

    /**
     * 车辆出场出口车道查询
     *
     * @return
     */
    @AutoLog(value = "车辆出场出口车道查询")
    @ApiOperation(value = "车辆出场出口车道查询", notes = "车辆出场出口车道查询")
    @GetMapping(value = "/parkArmOutInfoList")
    public Result<List<ParkArmInfo>> parkArmOutInfoList() {
        Result<List<ParkArmInfo>> result = new Result<>();
        QueryWrapper<ParkArmInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ParkArmInfo::getArmType, JddConstant.StringNumber.STRING_ONE);
        queryWrapper.lambda().eq(ParkArmInfo::getTargetAreaId, "");
        List<ParkArmInfo> pageList = parkArmInfoService.list(queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }
}
